﻿using System;
using System.Windows.Forms;
using EnvDTE;
using EnvDTE80;


namespace Lexware.Tools.ProjectPropertyOverview
{
    /// <summary>
    /// 
    /// </summary>
    public partial class ToolWindowControl : UserControl
    {
        #region Private Members

        private DTE2 _applicationObject;
        private SolutionEvents _solutionEvents;
        private ConfigurationPropertiesManager _configurationPropertiesManager;

        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="ToolWindowControl"/> class.
        /// </summary>
        public ToolWindowControl()
        {
            InitializeComponent();

            _configurationPropertiesManager = new ConfigurationPropertiesManager();
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the application object.
        /// </summary>
        /// <value>The application object.</value>
        public DTE2 ApplicationObject
        {
            get { return _applicationObject; }
            set
            {
                _applicationObject = value;
                if (_applicationObject != null)
                {
                    Events events = _applicationObject.Events;
                    if (events != null)
                    {
                    }

                    _configurationPropertiesManager.ApplicationObject = _applicationObject;

                    SolutionEventsOpened();
                }

                RegisterEvents();
            }
        }

        /// <summary>
        /// Gets or sets the parent tool window.
        /// </summary>
        /// <value>The parent tool window.</value>
        public Window ParentToolWindow { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// Unregisters the events.
        /// </summary>
        public void UnregisterEvents()
        {
            //// unregister events
            _solutionEvents.Opened -= SolutionEventsOpened;
            _solutionEvents.AfterClosing -= SolutionEventsClosed;
            _solutionEvents.ProjectAdded -= SolutionEventsProjectAdded;
            _solutionEvents.ProjectRemoved -= SolutionEventsProjectRemoved;

            //_projectConfigurationPropertiesCollectionBindingSource.CurrentItemChanged -= DataSourceCurrendItemChanged;
            _gridView.SelectionChanged -= GridViewSelectionChanged;
            _gridView.ColumnStateChanged -= GridViewFocusChanged;
            _gridView.CellValueChanged -= GridViewCellValueChanged;
            _gridView.CellBeginEdit -= GridViewCellValueChanging;
        }

        // To update Error Icons
        public void GridViewUpdate()
        {
            _gridView.SelectAll();
            _gridView.ClearSelection();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Registers the events.
        /// </summary>
        private void RegisterEvents()
        {
            if (_solutionEvents != null)
            {
                UnregisterEvents();
            }
            _solutionEvents = _applicationObject.Events.SolutionEvents;

            //// register new events
            _solutionEvents.Opened += SolutionEventsOpened;
            _solutionEvents.AfterClosing += SolutionEventsClosed;
            _solutionEvents.ProjectAdded += SolutionEventsProjectAdded;
            _solutionEvents.ProjectRemoved += SolutionEventsProjectRemoved;

            //_projectConfigurationPropertiesCollectionBindingSource.CurrentItemChanged += DataSourceCurrendItemChanged;
            _gridView.SelectionChanged += GridViewSelectionChanged;
            _gridView.ColumnStateChanged += GridViewFocusChanged;
            _gridView.CellValueChanged += GridViewCellValueChanged;
            _gridView.CellBeginEdit += GridViewCellValueChanging;
        }

        /// <summary>
        /// Solution_s the opened.
        /// </summary>
        private void SolutionEventsOpened()
        {
            _configurationPropertiesManager.ReadAllProjectProperties(_projectConfigurationPropertiesCollectionBindingSource);

            CustomizeSetDefaultButton();
            CustomizeLoadDefaultProjectButton();
            AlternatingColors();
            PaintErrorRowsRed();
        }

        /// <summary>
        /// _solutions the events_ closed.
        /// </summary>
        private void SolutionEventsClosed()
        {
            _projectConfigurationPropertiesCollectionBindingSource.Clear();
            AlternatingColors();
            PaintErrorRowsRed();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p">The p.</param>
        private void SolutionEventsProjectAdded(Project p)
        {
            SolutionEventsClosed();
            SolutionEventsOpened();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="deletedProject">The deleted project.</param>
        private void SolutionEventsProjectRemoved(Project deletedProject)
        {

            _gridView.BeginEdit(false);

            SolutionEventsClosed();
            _configurationPropertiesManager = new ConfigurationPropertiesManager { ApplicationObject = ApplicationObject };
            _configurationPropertiesManager.ReadAllProjectProperties(_projectConfigurationPropertiesCollectionBindingSource, deletedProject);

            _gridView.EndEdit();
            _gridView.Invalidate();
            _gridView.Refresh();

            AlternatingColors();
            PaintErrorRowsRed();
        }

        ///// <summary>
        ///// Handles the ButtonClick event of the repositoryItemPath control.
        ///// </summary>
        ///// <param name="sender">The source of the event.</param>
        ///// <param name="e">The <see cref="DevExpress.XtraEditors.Controls.ButtonPressedEventArgs"/> instance containing the event data.</param>
        //private void repositoryItemPath_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        //{
        //    ButtonEdit buttonEdit = sender as ButtonEdit;
        //    if (buttonEdit != null)
        //    {
        //        _buttonEditTextHack = (string)buttonEdit.EditValue;
        //        _folderBrowserDialog.SelectedPath = _buttonEditTextHack;

        //        if (_folderBrowserDialog.ShowDialog() == DialogResult.OK)
        //        {
        //            _buttonEditTextHack = _folderBrowserDialog.SelectedPath;
        //            buttonEdit.EditValue = _folderBrowserDialog.SelectedPath;
        //            buttonEdit.Text = _folderBrowserDialog.SelectedPath;
        //        }
        //    }
        //}


        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GridViewSelectionChanged(object sender, EventArgs e)
        {
            CustomizeSetDefaultButton();
            CustomizeLoadDefaultProjectButton();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GridViewFocusChanged(object sender, EventArgs e)
        {
            CustomizeSetDefaultButton();
            CustomizeLoadDefaultProjectButton();
        }

        /// <summary>
        /// Grids the view cell value changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void GridViewCellValueChanged(object sender, EventArgs e)
        {
            CustomizeSetDefaultButton();
            CustomizeLoadDefaultProjectButton();

            AlternatingColors();
            PaintErrorRowsRed();
        }

        /// <summary>
        /// Grids the view cell value changing.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void GridViewCellValueChanging(object sender, EventArgs e)
        {
            CustomizeSetDefaultButton();
            CustomizeLoadDefaultProjectButton();
        }

        /// <summary>
        /// 
        /// </summary>
        private void CustomizeSetDefaultButton()
        {
            // get selected rows from datasource
            Int32[] selectedIndex = new int[_gridView.SelectedRows.Count];

            int i = 0;
            foreach (DataGridViewRow item in _gridView.SelectedRows)
            {
                selectedIndex[i++] = item.Index;
            }

            if (selectedIndex.Length == 0)
            {
                // no row selected 
                SetDefaultButton.Enabled = false;
            }
            else
            {
                bool defaultButtonEnable = false;

                foreach (int index in selectedIndex)
                {
                    if (index > -1)
                    {
                        ProjectConfigurationProperties configuration = (ProjectConfigurationProperties)((BindingSource)_gridView.DataSource).Current;

                        if (!configuration.HasDefaultProperties())
                        {
                            defaultButtonEnable = true;
                            break;
                        }
                    }
                }

                SetDefaultButton.Enabled = defaultButtonEnable;
            }
        }

        /// <summary>
        /// Customizes the load default project button.
        /// </summary>
        private void CustomizeLoadDefaultProjectButton()
        {
            // get selected rows from datasource
            Int32[] selectedIndex = new int[_gridView.SelectedRows.Count];

            int i = 0;
            foreach (DataGridViewRow item in _gridView.SelectedRows)
            {
                selectedIndex[i++] = item.Index;
            }

            if (selectedIndex.Length == 0)
            {
                // no row selected 
                LoadDefaultProjectButton.Enabled = false;
            }
            else
            {
                bool defaultButtonEnable = false;

                if (selectedIndex.Length > 0)
                {
                    if (selectedIndex[0] > -1)
                    {
                        defaultButtonEnable = true;
                    }
                }

                LoadDefaultProjectButton.Enabled = defaultButtonEnable;
            }
        }

        /// <summary>
        /// set project properties from project file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LoadDefaultProjectButton_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDlg = new OpenFileDialog())
            {
                openFileDlg.Filter = LocalResources.OpenFileFilter;

                if (openFileDlg.ShowDialog() == DialogResult.OK)
                {
                    // get selected rows from datasource
                    Int32[] selectedIndex = new int[_gridView.SelectedRows.Count];

                    int i = 0;
                    foreach (DataGridViewRow item in _gridView.SelectedRows)
                    {
                        selectedIndex[i++] = item.Index;
                    }

                    Int32[] rowIndex = new Int32[selectedIndex.Length];

                    for (int j = 0; j < selectedIndex.Length; j++)
                    {
                        rowIndex[j] = _projectConfigurationPropertiesCollectionBindingSource.IndexOf(
                            _gridView.Rows[j].DataBoundItem);
                    }

                    if (selectedIndex.Length > 0)
                    {
                        Solution2 solution = (Solution2)_applicationObject.Solution;

                        try
                        {
                            Project project = solution.AddFromFile(openFileDlg.FileName);

                            _configurationPropertiesManager.SetDefaultConfigurationPropertiesFromProjectFile(rowIndex, project);

                            solution.Remove(project);

                            SolutionEventsProjectRemoved(project);
                        }
                        catch (Exception ex)
                        {

                            MessageBox.Show(ex.ToString(), LocalResources.ErrorOnLoadProject, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// set default project properties
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetDefaultButton_Click(object sender, EventArgs e)
        {
            // get selected rows from datasource
            Int32[] selectedIndex = new int[_gridView.SelectedRows.Count];

            int i = 0;
            foreach (DataGridViewRow item in _gridView.SelectedRows)
            {
                selectedIndex[i++] = item.Index;
            }

            if (selectedIndex.Length > 0)
            {
                foreach (int index in selectedIndex)
                {
                    if (index >= 0)
                    {
                        int rowIndex = _projectConfigurationPropertiesCollectionBindingSource.IndexOf(
                        _gridView.Rows[index].DataBoundItem);

                        ProjectConfigurationProperties configuration = (ProjectConfigurationProperties)((BindingSource)_gridView.DataSource).List[rowIndex];

                        _configurationPropertiesManager.SetDefaultConfigurationProperties(configuration);
                    }
                }

                // after we set the default values, disable DefaultButton
                SetDefaultButton.Enabled = false;

                _gridView.Invalidate();
                _gridView.Refresh();
            }
            else
            {
                MessageBox.Show(LocalResources.NoProjectRowSelectedError, LocalResources.GeneralError);
            }
        }

        private void GridViewDataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            errorProvider1.SetError(((DataGridView)sender).EditingControl, e.Exception.Message);
        }

        private void AlternatingColors()
        {
            string temp = null;
            int startindex = 0;
            bool changeStyle = false;
            DataGridViewCellStyle style1 = new DataGridViewCellStyle();
            DataGridViewCellStyle style2 = new DataGridViewCellStyle();
            style1.BackColor = System.Drawing.Color.Cornsilk;
            style2.BackColor = System.Drawing.Color.White;

            foreach (DataGridViewRow row in _gridView.Rows)
            {
                string projectName = row.Cells["projectNameDataGridViewTextBoxColumn"].Value.ToString();
                if (temp == null)
                {
                    temp = projectName;
                }
                else
                {
                    if (temp != projectName || row.Index == _gridView.Rows.Count - 1)
                    {
                        temp = projectName;
                        int endindex;
                        if (row.Index == _gridView.Rows.Count - 1)
                        {
                            endindex = row.Index;
                        }
                        else
                        {
                            endindex = row.Index - 1;
                        }

                        if (changeStyle)
                        {
                            for (int i = startindex; i <= endindex; i++)
                            {
                                _gridView.Rows[i].DefaultCellStyle = style1;
                            }
                        }
                        else
                        {
                            for (int i = startindex; i <= endindex; i++)
                            {
                                _gridView.Rows[i].DefaultCellStyle = style2;
                            }
                        }
                        changeStyle = !changeStyle;
                        startindex = row.Index;
                    }
                }
            }
        }

        private void ContextMenuStripItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            SetDefaultButton_Click(sender, e);
            AlternatingColors();
            PaintErrorRowsRed();
        }

        private void GridViewCellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
        {
            if (_gridView.SelectedRows.Count == 0)
            {
                _gridView.ClearSelection();
                _gridView.Rows[e.RowIndex].Selected = true;
            }
            e.ContextMenuStrip = contextMenuStrip;
        }

        private void PaintErrorRowsRed()
        {
            DataGridViewCellStyle styleRed = new DataGridViewCellStyle();
            styleRed.BackColor = System.Drawing.Color.Tomato;
            int columnIndex = statusDataGridViewCheckBoxColumn.Index;

            foreach (DataGridViewRow row in _gridView.Rows)
            {
                if ((bool)row.Cells[columnIndex].Value == false)
                {
                    row.DefaultCellStyle = styleRed;
                }
            }
        }

        #endregion
    }
}